package com.gitee.springioc.practice.service.impl;

import com.gitee.springioc.practice.entity.Partner;
import com.gitee.springioc.practice.service.PartnerInfoService;
import com.gitee.springioc.practice.service.PartnerRegistService;
import com.gitee.springioc.practice.service.PartnerService;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

/**
 * @author ming.yan-1
 * @version V1.0
 * @Title com.gitee.springioc.practice.service.impl
 * @Description
 * @date 2018/10/9  上午11:18
 */
@Service("partnerRegistServiceImpl")
public class PartnerRegistServiceImpl implements InitializingBean, ApplicationContextAware, PartnerRegistService{

    public static final String PARTNER_SERVICE_PREFIX = "partnerInfoService";

    @Resource(name = "partnerServiceImpl")
    private PartnerService partnerService;

    private ApplicationContext applicationContext;

    @Override
    public void afterPropertiesSet() throws Exception {
        regist();
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public void regist() {
        ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext)applicationContext;
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext.getBeanFactory();
        ArrayList<Partner> partners = partnerService.queryAllPartner();
        for(Partner partner:partners){
            try {
                if(!applicationContext.containsBean(PARTNER_SERVICE_PREFIX+partner.getPartnerNo())){
                    BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(PartnerInfoServiceImpl.class);
                    Class partnerClass = Partner.class;
                    Class partnerInfoClass = PartnerInfoServiceImpl.class;
                    Field[] fields = partnerClass.getDeclaredFields();
                    for(Field field:fields){
                        PropertyDescriptor pd = new PropertyDescriptor(field.getName(), partnerClass);
                        Method getMethod = pd.getReadMethod();
                        beanDefinitionBuilder.addPropertyValue(field.getName(),getMethod.invoke(partner));
                    }
                    defaultListableBeanFactory.registerBeanDefinition(PARTNER_SERVICE_PREFIX+partner.getPartnerNo(), beanDefinitionBuilder.getBeanDefinition());
                }
            } catch (IntrospectionException e) {

            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void regist(String partnerNo) {

    }

    @Override
    public PartnerInfoService find(String partnerNo) {
        return null;
    }
}
